/*
 * Level.cpp
 *
 *  Created on: 4 apr 2010
 *      Author: Andreas
 */

#include "Level.h"
#include "Base.h"
#include "Player.h"
#include "Block.h"
#include "engine/graphics/ScreenManager.h"
#include "engine/graphics/Image.h"
#include "engine/text/FontManager.h"
#include "engine/CollisionManager.h"

#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>

using namespace std;

namespace Single {

Level::Level(string file) {
	int keys[]={SDLK_UP,SDLK_LEFT,SDLK_DOWN,SDLK_RIGHT,SDLK_RCTRL};
	player = new Player(keys, Player::SHIP_RED);

	blocksCollected = blocksHolding = 0;
	showCollCircles = false;

	// Read data
	ifstream data(file.c_str());
	int tmp;
	int x, y;

	// Blocks
	data >> tmp;
	cout << tmp <<endl;
	for (int i=0; i<tmp; i++) {
		data >> x >> y;
		blocks.push_back(new Block(x, y));
	}

	// Guards
	data >> tmp;
	cout << tmp <<endl;
	for (int i=0; i<tmp; i++) {
		data >> x >> y;
		guards.push_back(new Guard(x, y));
	}

	// Base
	data >> x >> y;
	base = new Base(x, y);
	// Base new position
	data >> goalX >> goalY;
	cout << goalX << " " << goalY << endl;

	// Player start position
	data >> x >> y;
	player->moveTo(x, y);
	cout << x << " " << y << endl;

	// Image file
	string mapfile;
	data >> mapfile;
	cout << mapfile << endl;
	map = new Image(mapfile);
	map->setFixedToScr(false);

	data.close();

	cout << "Single::Level created" << endl;
}

Level::~Level() {

}


void Level::userInput(Uint8 *keys) {
	player->setKeysDown(keys);
}

void Level::handleEvents(SDL_Event *event) {
	// Toggle collision circles
	if (( event->type == SDL_KEYDOWN ) && ( event->key.keysym.sym == SDLK_c ) ) {
		showCollCircles = !showCollCircles;

		for (int i=0; i<blocks.size(); i++) {
			blocks[i]->showCollisionCircle(showCollCircles);
		}
		for (int i=0; i<guards.size(); i++) {
			guards[i]->showCollisionCircle(showCollCircles);
		}
		player->showCollisionCircle(showCollCircles);
		base->showCollisionCircle(showCollCircles);
	}
	if (( event->type == SDL_KEYDOWN ) && ( event->key.keysym.sym == SDLK_SPACE ) ) {
		cout << player->getXpos() << " " << player->getYpos() << endl;
	}
}

void Level::update(int elapsed) {
	/** Set camera and update player position **/
	ScreenManager::setCamera(player->getXpos(), player->getYpos());
	player->updatePos(0);

	/** Blocks Loop **/
	for (int i=0; i<blocks.size(); i++) {
		if (blocks[i]->isActive()) {
			/** Collision with blocks **/
			if ( CollisionManager::circleCollision( player->getXpos(),
					player->getYpos(),
					player->getRadius(),
					blocks[i]->getXpos(),
					blocks[i]->getYpos(),
					blocks[i]->getRadius()) ) {

				blocks[i]->setActive(false);
				blocksHolding++;
			}
		}
		else {
			/** Update respawn timer of non-active blocks **/
			blocks[i]->update(elapsed);
		}
	}

	/** Player collision with base **/
	if ( CollisionManager::circleCollision( player->getXpos(),
			player->getYpos(),
			player->getRadius(),
			base->getXpos(),
			base->getYpos(),
			base->getRadius()) ) {

		blocksCollected += blocksHolding;
		blocksHolding = 0;
	}

	/** Player and bullet pixelperfect collision with background **/
	if (CollisionManager::pixelCollision( map->getSurface(),
			player->getXpos(),
			player->getYpos())) {

		player->moveTo(0, 0);
	}

	for (int j=0; j<player->getBullets().size(); j++) {
		if (CollisionManager::pixelCollision( map->getSurface(),
				player->getBullets()[j]->getXpos(),
				player->getBullets()[j]->getYpos())) {

			player->removeBullet(j);
		}
	}
}

void Level::drawScene() {

	map->draw();

	if (map->fixedToScr) {
		cout << "true" << endl;
	}
	for (int i=0; i<blocks.size(); i++) {
		blocks[i]->draw();
	}

	for (int i=0; i<guards.size(); i++) {
		guards[i]->draw();
	}

	base->draw();

	player->draw();

	{
		stringstream ss;
		ss << blocksCollected;
		FontManager::drawText(ss.str(), (int)ScreenManager::screenXpos((base->getXpos()-10)),
												(int)ScreenManager::screenYpos((base->getYpos()-60)), "lucida16");
	}

	{
		stringstream ss;
		ss << blocksHolding;
		FontManager::drawText(ss.str(), (int)ScreenManager::screenXpos((player->getXpos())),
										(int)ScreenManager::screenYpos((player->getYpos()-40)), "lucida16");

	}

}

}
